﻿/*
Copyright (C) 2009  Tomasz Chrzanowski

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/

using System;

namespace Com.TomCdc.ChangeDataCapture
{
    /// <summary>
    /// Represents a collection of objects that can be iterated forward and backward.
    /// </summary>
    /// <typeparam name="T">A type of element in the collection.</typeparam>
    class Selector<T>:ISelector<T>
    {
        /// <summary>
        /// The array of elements to iterate.
        /// </summary>
        private readonly T[] _srcRecords;

        /// <summary>
        /// The possition of current element in the collection.
        /// </summary>
        private int _index;

        /// <summary>
        /// Initializes a new instance of <see cref="Selector"/> class with the provided array.
        /// </summary>
        /// <param name="sourceRecords">An array of <see cref="SourceRecord"/> objects.</param>
        public Selector(T[] sourceRecords)
        {
            _srcRecords = sourceRecords;
            _index = -1;
        }


        /// <summary>
        /// Gets next element from the collection.
        /// </summary>
        /// <returns>The next element.</returns>
         public T GetNext()
        {
            if (_index + 1 < _srcRecords.Length)
            {
                return _srcRecords[++_index];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

         /// <summary>
         /// Gets previous element from the collection.
         /// </summary>
         /// <returns>The previous element.</returns>
        public T GetPrevious()
        {
            if (_index - 1 >= 0)
            {
                return _srcRecords[--_index];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }            
        }

        /// <summary>
        /// Gets current element from the collection.
        /// </summary>
        /// <returns>The current element.</returns>
        public T GetCurrent()
        {
            if (_index >= 0 && _index < _srcRecords.Length)
            {
                return _srcRecords[_index];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        /// <summary>
        /// Gets value indicating whether exists next element in the collection.
        /// </summary>
        /// <returns>True if next element exists.</returns>
        public bool IsNext()
        {
            if (_index + 1 < _srcRecords.Length) return true;
            return false;
        }

        /// <summary>
        /// Gets value indicationg whether exists next wlement in the collection.
        /// </summary>
        /// <returns></returns>
        public bool IsPrevious()
        {
            if (_index - 1 >= 0) return true;
            return false;
        }

        /// <summary>
        /// Returns the number of element in the collection.
        /// </summary>
        public int Count
        {
            get
            {
                return _srcRecords.Length;
            }
        }
    }
}
